home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / asmutl / usoftpd.arc / MACRO.DOC < prev    next >
Text File  |  1987-07-31  |  18KB  |  661 lines

  1.          Calling Macros in DOS.INC and BIOS.INC
  2.  
  3. You are    responsible for    saving and restoring registers used in
  4. macros.    The "Registers used" field identifies registers    to save.
  5.  
  6. Macros that accept address parameters use internal macros that
  7. allow you to specify addresses in several ways.    The macro
  8. automatically identifies the type of the argument and handles it
  9. appropriately. For example, assume the following declarations:
  10.  
  11.   String    DB     "test$"
  12.   pString   DW     Str
  13.   fpString  DD     Str
  14.  
  15. Given these values, the    macro @DispStr (which displays the string
  16. at DS:DX) has the following effects:
  17.  
  18.   Kind of argument        Example          Value    loaded
  19.  
  20.   Label    of byte    variable    @DispStr String      DS:OFFSET String
  21.   Near pointer variable        @DispStr pString      DS:pString
  22.   Far pointer variable        @DispStr fpString      fpString[2]:fpString[0]
  23.   Constant            @DispStr 0          DS:0
  24.   Pointer in register        @DispStr si          DS:SI
  25.   Near Pointer with segment @DispStr pString,es      ES:pString
  26.   Constant with    segment        @DispStr 0,es      ES:0
  27.   Register with    segment        @DispStr di,es      ES:DI
  28.  
  29. Note that if a far pointer or a    segment    is given, DS must be
  30. saved before the macro call and    restored afterward. Segments may
  31. be given as registers, constants, or word variables.
  32.  
  33. In syntax, parameters enclosed in brackets are optional.
  34. Paramaters sometimes have a leading symbol to indicate that the
  35. argument must have a certain type, as shown below:
  36.  
  37.   Leading Symbol   Example    Limitation
  38.  
  39.     #       #return    Must be    constant
  40.     &       &vector    Must be    offset address as described above
  41.     $       $terminator    May be constant    or register, but not memory
  42.  
  43. Parameters with    no leading symbol may be constants, registers, or
  44. variables. Parameters are 16-bit except    where noted in the description.
  45.  
  46. Symbols    must be    previously defined before they can be passed as
  47. arguments to most of the DOS macros. Generally this means that
  48. data must be declared before code in the source    file.
  49.  
  50.           DOS Macro Syntax and Description
  51.  
  52. KEYBOARD INPUT
  53.  
  54. @GetKey    (01h, 07h, 08h,    0Ch)
  55.  
  56. Gets a keystroke from the keyboard
  57.  
  58. Syntax:        @GetKey    [#echo]    [,[#break] [,#clearbuf]]
  59.  
  60. Arguments:    echo        = nonzero to echo keystroke    - default yes
  61.         break        = nonzero to accept    Control-C - default yes
  62.         clearbuf    = nonzero to clear keyboard    buffer - default no
  63.         (Arguments may be omitted to get defaults)
  64. Return:        ASCII code of key in AL
  65. Registers used:    AX used    for all, DL used if echo on and    ctrl-c off
  66.  
  67.  
  68. @GetStr    (0Ah)
  69.  
  70. Gets a string from the keyboard
  71.  
  72. Syntax:        @GetStr    &buffer    [,[$terminator]    [,[#limit] [,segment]]]
  73.  
  74. Arguments:    buffer        = Offset of    buffer where string will be stored
  75.             Byte 1  = Maximum length of    string (before call)
  76.             Byte 2  = Actual length of string (after call)
  77.             Byte 3+ = Bytes of string
  78.         terminator  = Terminating byte - usually null (0) or $ (24h)
  79.         limit        = Maximum length of    string (if not given as
  80.                   argument,    must be    in buffer before macro call)
  81.         segment        = Segment of buffer    (DS if not given)
  82. Return:        Pointer    to string in SI, length    of string in BX
  83. Registers used:    AX, DX,    BX, SI
  84.  
  85. OUTPUT
  86.  
  87. @DispCh    (02h)
  88.  
  89. Displays one or    more characters    to screen
  90.  
  91. Syntax:        @DispCh    char [,char]...
  92.  
  93. Arguments:    char        = 8-bit ASCII code
  94. Return:        Code in    AL
  95. Registers used:    AX and DL
  96.  
  97.  
  98. @PrtCh (05h)
  99.  
  100. Prints one or more characters to LPT1
  101.  
  102. Syntax:        @PrtCh char [,char]...
  103.  
  104. Arguments:    char        = 8-bit ASCII code
  105. Return:        Code in    AL
  106. Registers used:    AX and DL
  107.  
  108.  
  109. @DispStr (09h)
  110.  
  111. Displays a $-terminated    string
  112.  
  113. Syntax:        @DispStr &address [,segment]
  114.  
  115. Arguments:    address        = Address of string    terminated by "$" (24h)
  116.         segment        = Segment of address string    (DS if not given)
  117. Return:        None
  118. Registers used:    AX and DS
  119.  
  120. DEVICE I/O
  121.  
  122. @Read (3Fh)
  123.  
  124. Reads data from    a file or device
  125.  
  126. Syntax:        @Read &buffer, length [,[handle] [,segment]]
  127.  
  128. Arguments:    buffer        = Offset of    buffer where data will be stored
  129.         length        = Length of    data in    bytes
  130.         handle        = File or device handle; if    none given,
  131.                   keyboard (handle 0) is assumed
  132.         segment        = Segment of address string    (DS if not given)
  133. Return:        If carry clear,    bytes read in AX
  134. Registers used:    Always AX, DX, BX, and CX; DS if segment changed
  135.  
  136.  
  137. @Write (40h)
  138.  
  139. Writes data to a file or device
  140.  
  141. Syntax:        @Write &buffer,    length,    [,[handle] [,segment]]
  142.  
  143. Arguments:    buffer        = Offset of    buffer where data is stored
  144.         length        = Length of    data in    bytes
  145.         handle        = File or device handle; if    none given, screen
  146.                   (handle 1) is assumed
  147.         segment        = Segment of address string    (DS if not given)
  148. Return:        If carry clear,    bytes written in AX
  149. Registers used:    Always AX, DX, BX, and CX; DS if segment changed
  150.  
  151. FILE CONTROL
  152.  
  153. @MakeFil (3Ch, 5Ah, 5Bh)
  154.  
  155. Creates    a file
  156.  
  157. Syntax:        @MakeFil &path [,[attrib] [,[segment] [,#kind]]]
  158.  
  159. Arguments:    path        = ASCIIZ string of file
  160.         attrib        = File atrribute (0    is default if none given)
  161.         segment        = Segment of address string    (DS if not given)
  162.         kind        = If none given, a file is always created even if
  163.                   one already exists. Under    DOS 3+ "tmp" can be
  164.                   given to create a    unique file or "new" to    create
  165.                   file only    if one doesn't already exist.
  166. Return:        If carrry clear, file handle in    AX
  167. Registers used:    Always AX, DX, and CX; DS if segment changed
  168.  
  169.  
  170. @OpenFil (3Dh)
  171.  
  172. Opens a    file for input or output
  173.  
  174. Syntax:        @OpenFil &path,    #access    [,segment]
  175.  
  176. Arguments:    path        = ASCIIZ string of file
  177.         access        = File access code
  178.         segment        = Segment of address string    (DS if not given)
  179. Return:        If carrry set, error code in AX
  180. Registers used:    Always AX and DX; DS if    segment    changed
  181.  
  182.  
  183. @ClosFil (3Eh)
  184.  
  185. Closes an open file handle
  186.  
  187. Syntax:        @ClosFil handle
  188.  
  189. Arguments:    handle        = Previously opened    file handle
  190. Return:        If carrry set, error code in AX
  191. Registers used:    AX and BX
  192.  
  193.  
  194. @DelFil    (41h)
  195.  
  196. Deletes    a specified file
  197.  
  198. Syntax:        @DelFil    &path [,segment]
  199.  
  200. Arguments:    path        = Offset of    ASCIIZ filespec
  201.         segment        = Segment of path (DS if none given)
  202. Return:        If carrry set, error code in AX
  203. Registers used:    AX and DX; DS if segment changed
  204.  
  205. @MoveFil (56h)
  206.  
  207. Moves or renames a file    by changing its    path specification.
  208.  
  209. Syntax:        @MoveFil &old, &new [,[segold] [,segnew]]
  210.  
  211. Arguments:    old        = Offset of    file spec to be    renamed
  212.         new        = Offset of    new file spec
  213.         segold        = Segment of old name (DS if none given)
  214.         segnew        = Segment of new name (ES if none given)
  215. Return:        If carry set, error code in AX
  216. Registers used:    AX, DX,    and DI;    DS and ES if corresponding segments changed
  217.  
  218.  
  219. @GetFirst (4Eh)    and @GetNext (4Fh)
  220.  
  221. Parses file specifications (optionally including wild cards) into
  222. file names
  223.  
  224. Syntax:        @GetFirst &path    [,[attribute] [,segment]]
  225.         @GetNext
  226.  
  227. Arguments:    path        = Offset of    ASCIIZ filespec    (can have wild cards)
  228.         attribute   = File attribute to    search for (0 for normal if
  229.                   none given)
  230.         segment        = Segment of path (DS if none given)
  231. Return:        If carrry set, error code in AX
  232. Registers used:    @GetFirst   = AX, CX, and DX; DS if segment changed
  233.         @GetNext    = AX only
  234.  
  235.  
  236. @GetDTA    (1Ah) and @SetDTA (2Fh)
  237.  
  238. Gets or    sets the Disk Transfer Address (DTA)
  239.  
  240. Syntax:        @GetDTA
  241.         @SetDTA    &buffer    [,segment]
  242.  
  243. Arguments:    buffer        = Offset of    new DTA    buffer
  244.         segment        = Segment of new DTA buffer    (DS if none given)
  245. Return:        @GetDTA        = ES:BX points to DTA
  246.         @SetDTA        = None
  247. Registers used:    AX for both; DS    and DX for @SetDTA; ES and BX for @GetDTA
  248.  
  249. @GetFilSz (42h)
  250.  
  251. Gets the file size by moving the file pointer to end of    the file.
  252. Note that the file pointer is reset to zero. Thus this macro should
  253. not be called during operations    that move the pointer.
  254.  
  255. Syntax:        @GetFilSz handle
  256.  
  257. Arguments:    handle        = Previously opened    file handle
  258. Return:        If carrry clear, file length in    DX:AX
  259. Registers used:    AX, BX,    CX, and    DX
  260.  
  261.  
  262. @MovePrtAbs and    @MovePtrRel (42h)
  263.  
  264. Moves the file pointer in an open file.    The pointer can    be moved to
  265. an absolute position, or relative to its current position.
  266.  
  267. Syntax:        @MovePrtAbs handle [,distance]
  268.         @MovePrtRel handle [,distance]
  269.  
  270. Arguments:    handle        = Previously opened    file handle
  271.         distance    = Distance to move pointer - must be a 16-bit
  272.                   constant or a 16-    or 32-bit variable; or
  273.                   leave blank and set distance in CX:DX before
  274.                   macro call
  275. Return:        If carrry clear, file pointer position in DX:AX
  276. Registers used:    AX, BX,    CX, and    DX
  277.  
  278. DIRECTORY CONTROL
  279.  
  280. @MkDir,    (39h), @RmDir (3Ah), and @ChDir    (3Bh)
  281.  
  282. Creates, deletes, or changes to    the specified directory
  283.  
  284. Syntax:        @MkDir &path [,segment]
  285.         @RmDir &path [,segment]
  286.         @ChDir &path [,segment]
  287.  
  288. Arguments:    path        = Offset of    ASCIIZ string to
  289.         segment        = Segment of path (DS if none given)
  290. Return:        If carrry set, error code in AX
  291. Registers used:    AX and DX; DS if segment changed
  292.  
  293.  
  294. @GetDir    (47h)
  295.  
  296. Returns    the current directory of the specified drive
  297.  
  298. Syntax:        @GetDir    &path [,[drive]    [,segment]]
  299.  
  300. Arguments:    buffer        = Offset of    buffer to receive ASCIIZ directory
  301.         drive        = 8-bit drive number - 0=current, 1=A, 2=B,    etc.
  302.                   (0 if none given)
  303.         segment        = Segment of path (DS if none given)
  304. Return:        If carrry set, error code in AX
  305. Registers used:    AX, SI,    and DL;    DS if segment changes
  306.  
  307.  
  308. DRIVE CONTROL
  309.  
  310. @GetDrv    (0Eh) and @SetDrv (19h)
  311.  
  312. Gets or    sets the current drive
  313.  
  314. Syntax:        @GetDrv
  315.         @SetDrv    drive
  316.  
  317. Argument:    drive        = 8-bit drive number (0=A, 1=B, etc.)
  318. Return:        @GetDrv        = Drive number in AL (0=A, 1=B, etc.)
  319.         @SetDrv        = Number of    drives in AL
  320. Registers used:    AX for both; DL    for @SetDrv
  321.  
  322.  
  323. @ChkDrv    (36h)
  324.  
  325. Gets various data about    a disk
  326.  
  327. Syntax:        @ChkDrv    [drive]
  328.  
  329. Argument:    drive        = 8-bit drive number (0=current,A=1, B=2, etc.);
  330.                   if none given, current assumed
  331. Return:        AX        = Sectors per cluster (-1 if drive invalid)
  332.         BX        = Available    clusters
  333.         CX        = Bytes per    sector
  334.         DX        = Clusters per drive
  335. Registers used:    AX, BX,    CX, and    DX
  336.  
  337. PROCESS    CONTROL
  338.  
  339. @Exit (4Ch)
  340.  
  341. Exits to DOS with return code
  342.  
  343. Syntax:        @Exit [#return]
  344.  
  345. Argument:    return        = 8-bit code to return to DOS; if none given,
  346.                   AL is used
  347. Return:        None
  348. Registers used:    AX
  349.  
  350.  
  351. @Exec (4Bh)
  352.  
  353. Executes a child process or an overlay
  354.  
  355. Syntax:        @Exec path, params [,[segpath] [,[segparams] [,overlay]]]
  356.  
  357. Arguments:    path        = Offset of    ASCIIZ filespec    to be executed
  358.         params        = Offset of    process    parameter block
  359.         segpath        = Segment of filespec (DS if none given)
  360.         segparams   = Segment of parameter block (ES if    none given)
  361.         overlay        = If not defined, normal process executed;
  362.                   if defined, overlay executed
  363. Return:        If carry set, error code
  364. Registers used:    AX, SI,    and DI;    DS and ES if corresponding segments given
  365.  
  366.  
  367. @GetRet    (4Dh)
  368.  
  369. Gets the return    code of    a child    process
  370.  
  371. Syntax:        @GetRet
  372.  
  373. Argument:    None
  374. Return:        Return code in AX
  375. Register used:    AX
  376.  
  377.  
  378. @TSR (31h)
  379.  
  380. Terminates a program, but leaves it resident in    memory
  381.  
  382. Syntax:        @TSR paragraphs    [,#return]
  383.  
  384. Arguments:    return        = Code to return to    DOS; if    none, AL used
  385.         paragraphs  = Memory in    paragraphs (16 bytes) to
  386.                   allocate for resident program
  387. Return:        None
  388. Registers used:    AX and DX
  389.  
  390. MEMORY CONTROL
  391.  
  392. @FreeBlok (49h)
  393.  
  394. Frees a    block of memory
  395.  
  396. Syntax:        @FreeBlok [segment]
  397.  
  398. Argument:    segment        = Starting address of memory to be freed;
  399.                   if none, ES address assumed
  400. Return:        If carry set, error code in AX
  401. Register used:    AX; ES if segment given
  402.  
  403.  
  404. @GetBlok (48h)
  405.  
  406. Allocates a block of memory
  407.  
  408. Syntax:        @GetBlok paragraphs
  409.  
  410. Argument:    paragraphs  = Paragraphs (16 bytes) of memory wanted
  411. Return:        AX and ES   = Segment address of allocated memory
  412.         BX        = Paragraphs actually allocated (may be
  413.                   less than    requested if memory is short)
  414. Register used:    AX and BX
  415.  
  416.  
  417. @ModBlok (48h)
  418.  
  419. Modifies an allocated block of memory
  420.  
  421. Syntax:        @ModBlok paragraphs [,segment]
  422.  
  423. Argument:    paragraphs  = Paragraphs (16 bytes) of memory wanted
  424.         segment        = Starting address of memory to be freed;
  425.                   if none, ES address assumed
  426. Return:        If carry set, error code in AX,    else:
  427.             ES  = Segment address of allocated memory
  428.             BX  = If carry is clear, paragraphs allocated
  429. Register used:    AX and BX; ES if segment given
  430.  
  431. MISCELLANEOUS
  432.  
  433. @GetDate (2Ah) and @SetDate (2Bh)
  434.  
  435. Gets or    sets the system    date
  436.  
  437. Syntax:        @GetDate
  438.         @SetDate month,    day, year
  439.  
  440. Arguments:    year        = 16-bit year (1980-2099)
  441.         month        = 8-bit month (1-12)
  442.         day        = 8-bit day    (1-31)
  443. Return:        For @GetDate:
  444.             AL  = Day of week (0 = Sunday, 1 = Monday, etc.)
  445.             CX  = Year (1980-2099)
  446.             DL  = Month (1-12)
  447.             DH  = Day (1-31)
  448.         For @SetDate:
  449.             AL  = If date was valid    0, else    -1
  450. Registers used:    AX, CX,    and DX
  451.  
  452.  
  453. @GetTime (2Ch) and @SetTime (2Dh)
  454.  
  455. Gets or    sets the system    time
  456.  
  457. Syntax:        @GetTime
  458.         @SetTime hour,minute,second,hundredth
  459.  
  460. Arguments:    hour        = 8-bit hour (0-23)
  461.         minute        = 8-bit hour (0-59)
  462.         second        = 8-bit hour (0-59)
  463.         hundredth   = 8-bit hour (0-99)
  464. Return:        For @GetTime:
  465.             CL  = Hour (0-23)
  466.             CH  = Minute (0-59)
  467.             DL  = Second (0-59)
  468.             DH  = Hundredth    (0-99)
  469.         For @SetTime:
  470.             AL  = If time was valid    0, else    -1
  471. Registers used:    AX, CX,    and DX
  472.  
  473.  
  474. @GetVer    (30h)
  475.  
  476. Gets the DOS version
  477.  
  478. Syntax:        @GetVer
  479.  
  480. Argument:    None
  481. Return:        AL        = Major version (0 for versions prior to 2.0)
  482.         AH        = Minor version
  483.         BH        = OEM serial number
  484.         BL:CX        = 24-bit user number
  485. Register used:    AX, BX,    and CX
  486.  
  487. @GetInt    (35h) and @SetInt (25h)
  488.  
  489. Gets or    sets the vector    for a specified    interrupt routine
  490.  
  491. Syntax:        @GetInt    #interrupt
  492.         @SetInt    #interrupt, &vector [,segment]
  493.  
  494. Arguments:    interrupt   = 8-bit interrupt number
  495.         vector        = Offset of    interrupt routine
  496.         segment        = Segment of routine - if none given, DS assumed
  497.                   for data;    segment    ignored    for code labels
  498. Return:        @GetInt        = None
  499.         @SetInt        = ES:BX points to interrupt    routine
  500. Registers used:    AX for both; ES    and BX for @GetInt; DS and DS for @SetInt
  501.  
  502.          BIOS Macro Syntax and Description
  503.  
  504.  
  505. MODE, PAGE, AND    COLOR CONTROL
  506.  
  507. @GetMode (I 10h    F 0Fh)
  508.  
  509. Gets the current video mode and    page
  510.  
  511. Syntax:        @GetMode
  512.  
  513. Arguments:    None
  514. Return:        AL        = Mode
  515.         AH        = Width in characters
  516.         BH        = Page
  517. Registers used:    AX and BH
  518.  
  519.  
  520. @SetMode (I 10h    F 00h)
  521.  
  522. Gets the current video mode and    page
  523.  
  524. Syntax:        @SetMode mode
  525.  
  526. Arguments:    mode        = 8-bit video mode
  527. Return:        none
  528. Registers used:    AX
  529.  
  530.  
  531. @SetColor (I 10h F 0Bh)
  532.  
  533. Sets the background color
  534.  
  535. Syntax:        @SetColor color
  536.  
  537. Arguments:    color        = 8-bit background color (0-15);
  538.                   border color in text modes
  539. Return:        none
  540. Registers used:    AX and BX
  541.  
  542.  
  543. @SetPalet (I 10h F 0Bh)
  544.  
  545. Sets the color palette
  546.  
  547. Syntax:        @SetPalet color
  548.  
  549. Arguments:    color        = 8-bit color palette (0-1 for modes 5 and 6)
  550. Return:        none
  551. Registers used:    AX and BX
  552.  
  553. @SetPage (I 10h    F 05h)
  554.  
  555. Sets the video page
  556.  
  557. Syntax:        @SetPage page
  558.  
  559. Arguments:    page        = 8-bit page number; 0-3 for modes 2 and 3
  560. Return:        none
  561. Registers used:    AX
  562.  
  563.  
  564. CHARACTER AND CURSOR CONTROL
  565.  
  566. @GetCur    (I 10h F 04h)
  567.  
  568. Gets the cursor    position and size
  569.  
  570. Syntax:        @GetCur    [page]
  571.  
  572. Arguments:    page        = 8-bit page with cursor (if none, 0 assumed)
  573. Return:        DL        = Column
  574.         DH        = Row
  575.         CL        = Starting scan line
  576.         CH        = Ending scan line
  577. Registers used:    AX, DX,    CX, and    BH
  578.  
  579.  
  580. @SetCurPos (I 10h F 02h)
  581.  
  582. Sets the cursor    position
  583.  
  584. Syntax:        @SetCurSz [column] [,[row] [,page]]
  585.  
  586. Arguments:    column        = 8-bit column; if none, DL    used
  587.         row        = 8-bit row; if none, DH used
  588.         page        = 8-bit page with cursor (if none, 0 assumed)
  589. Return:        none
  590. Registers used:    AX, DX,    and BH
  591.  
  592.  
  593. @SetCurSz (I 10h F 01h)
  594.  
  595. Sets the cursor    size and shape by specifying active scan lines.    The
  596. CGA adapter the    lines are 0-7. The monochrome adapter has lines    0-13.
  597.  
  598. Syntax:        @SetCurSz startline, endline
  599.  
  600. Arguments:    startline   = 8-bit starting scan line (default    CGA=6; MA=12)
  601.         endline        = 8-bit ending scan    line (default CGA=7; MA=13)
  602. Return:        none
  603. Registers used:    AX and CX
  604.  
  605. @GetChAtr (I 10h F 08h)
  606.  
  607. Gets the character and attribute at the    cursor location
  608.  
  609. Syntax:        @GetChAtr [page]
  610.  
  611. Arguments:    page        = 8-bit page to check (if none, 0 assumed)
  612. Return:        AH        = Attribute
  613.         AL        = ASCII character
  614. Registers used:    AX and BH
  615.  
  616.  
  617. @PutChAtr (I 10h F 09h)    and @PutCh (I 10h F 0Ah)
  618.  
  619. Puts one or more characters and    attributes at the current cursor
  620. position. For @PutCh, the current attribute is used in text modes
  621. and any    specified attribute is ignored.
  622.  
  623. Syntax:        @PutChAtr [character] [,[attrib] [,[page] [,count]]]
  624.  
  625. Arguments:    character   = 8-bit ASCII character to put; if none, AL    used
  626.         attrib        = 8-bit attribute to put; if none, BL used
  627.         page        = 8-bit page to put    on (if none, 0 assumed)
  628.         count        = Number to    put (if    none, 1    assumed)
  629. Return:        AH        = Attribute
  630.         AL        = ASCII character
  631. Registers used:    AX, BX,    CX
  632.  
  633.  
  634. @Scroll    (I 10h F 06h and 07h)
  635.  
  636. Scrolls    a specified window up or down
  637.  
  638. Syntax:        @Scroll    dist [,[attr] [,[uprow [,[upcol    [,[dnrow] [,dncol]]]]]
  639.  
  640. Arguments:    dist        = 8-bit number of lines to scroll; positive
  641.                   scrolls down; negative scrolls up; 0 clears
  642.         attr        = 8-bit attribute for blank    lines (if none,    07h)
  643.         uprow        = Upper left row (if none, CH used)
  644.         upcol        = Upper left column    (if none, CL used)
  645.         dnrow        = Lower right row (if none,    DH used)
  646.         dncol        = Lower right column (if none, DL used)
  647. Return:        none
  648. Registers used:    AX, CX,    DX, and    BH
  649.  
  650.  
  651. @Cls (I    10h F 06, 08h, and 02h)
  652.  
  653. Clears the screen of the current page
  654.  
  655. Syntax:        @Cls
  656.  
  657. Arguments:    None
  658. Return:        None
  659. Registers used:    AX, BX,    CX, and    DX
  660.  
  661.